using System.Collections.Generic;

namespace IQIGame.Onigao.Framework.Serialization
{
    public static class SerializeCustomPODUtil
    {
        public static void SerializeObject(SOutputStream _buf, ISerializeCustomPOD rObject)
        {
            _buf.Write_boolean(rObject != null);
            if (rObject != null)
            {
                rObject.Serialize(_buf);
            }
        }

        public static bool DeSerializeObject<T>(SInputStream _buf, ref T rObject) where T : ISerializeCustomPOD, new()
        {
            var bNotNull = _buf.Read_boolean();
            if (bNotNull)
            {
                if (rObject == null)
                {
                    rObject = new T();
                }
                rObject.DeSerialize(_buf);
                return true;
            }
            return false;
        }

        public static void SerializeList<T>(SOutputStream _buf, List<T> rList) where T : ISerializeCustomPOD
        {
            _buf.Write_int(rList.Count);
            for (int i = 0; i < rList.Count; i++)
            {
                SerializeObject(_buf, rList[i]);
            }
        }

        public static void DeSerializeList<T>(SInputStream _buf, ref List<T> rList) where T : ISerializeCustomPOD, new()
        {
            var nCount = _buf.Read_int();
            if (rList == null)
            {
                rList = new List<T>(nCount);
            }

            for (int i = 0; i < nCount; i++)
            {
                T rObject = new T();
                DeSerializeObject(_buf, ref rObject);
                rList.Add(rObject);
            }
        }

        public static void SerializeListInt(SOutputStream _buf, List<int> rList)
        {
            _buf.Write_int(rList.Count);
            for (int i = 0; i < rList.Count; i++)
            {
                _buf.Write_int(rList[i]);
            }
        }

        public static void DeSerializeListInt(SInputStream _buf, ref List<int> rList)
        {
            var nCount = _buf.Read_int();
            if (rList == null)
            {
                rList = new List<int>(nCount);
            }

            for (int i = 0; i < nCount; i++)
            {
                rList.Add(_buf.Read_int());
            }
        }

        public static void SerializeIntDict<T>(SOutputStream _buf, Dictionary<int, T> rDict) where T : ISerializeCustomPOD
        {
            _buf.Write_int(rDict.Count);
            foreach (var rPair in rDict)
            {
                _buf.Write_int(rPair.Key);
                SerializeObject(_buf, rPair.Value);
            }
        }

        public static void DeSerializeIntDict<T>(SInputStream _buf, ref Dictionary<int, T> rDict) where T : ISerializeCustomPOD, new()
        {
            var nCount = _buf.Read_int();
            if (rDict == null)
            {
                rDict = new Dictionary<int, T>();
            }

            for (int i = 0; i < nCount; i++)
            {
                T rValue = new T();
                var nKey = _buf.Read_int();
                DeSerializeObject(_buf, ref rValue);
                rDict.TryAdd(nKey, rValue);
            }
        }
        
        public static void SerializePOD(SOutputStream _buf, IPOD rObject)
        {
            _buf.Write_boolean(rObject != null);
            if (rObject != null)
            {
                rObject.Serial(_buf);
            }
        }

        public static bool DeSerializePOD<T>(SInputStream _buf, ref T rObject) where T : IPOD, new()
        {
            var bNotNull = _buf.Read_boolean();
            if (bNotNull)
            {
                if (rObject == null)
                {
                    rObject = new T();
                }
                rObject.UnSerial(_buf);
                return true;
            }
            return false;
        }

    }
}
